﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Security;
using Newtonsoft.Json;

namespace Gueei.Gallery.Security
{
	public class SimpleJsonRoleProvider: RoleProvider
	{
		Dictionary<string, ISet<string>> UserRoles { get; set; }

		private string JsonFilePath { get; set; }

		public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config)
		{
			base.Initialize(name, config);
			JsonFilePath = HttpContext.Current.Server.MapPath(
				config["JsonFilePath"] ?? "~\\App_Data\\userRoles.js");
			// Load file
// ReSharper disable AssignNullToNotNullAttribute
			Directory.CreateDirectory(Path.GetDirectoryName(JsonFilePath));
// ReSharper restore AssignNullToNotNullAttribute
			if (File.Exists(JsonFilePath))
			{
				try
				{
					string json = "";
					using (var fs = new StreamReader(JsonFilePath))
					{
						json = fs.ReadToEnd();
					}
					UserRoles = JsonConvert.DeserializeObject<Dictionary<string, ISet<string>>>(json);
				}
				catch
				{
					UserRoles = new Dictionary<string, ISet<string>>();
				}
			}
			else
			{
				UserRoles = new Dictionary<string, ISet<string>>();
			}
		}

		private void Save()
		{
			var json = JsonConvert.SerializeObject(UserRoles);
			using (var fs = new StreamWriter(JsonFilePath))
			{
				fs.WriteLine(json);
			}
		}

		public override void AddUsersToRoles(string[] usernames, string[] roleNames)
		{
			throw new NotImplementedException();
		}

		public override string ApplicationName
		{
			get;
			set;
		}

		public override void CreateRole(string roleName)
		{
			throw new NotImplementedException();
		}

		public override bool DeleteRole(string roleName, bool throwOnPopulatedRole)
		{
			throw new NotImplementedException();
		}

		public override string[] FindUsersInRole(string roleName, string usernameToMatch)
		{
			throw new NotImplementedException();
		}

		public override string[] GetAllRoles()
		{
			return GalleryRoles.AllRoles;
		}

		public override string[] GetRolesForUser(string username)
		{
			if (!UserRoles.ContainsKey(username)) AddUserWithDefaultRoles(username);
			return UserRoles[username].ToArray();
		}

		public override string[] GetUsersInRole(string roleName)
		{
			if (!RoleExists(roleName)) return new string[] {};

			return UserRoles.Where(ur => ur.Value.Contains(roleName)).Select(ur => ur.Key).ToArray();
		}

		public override bool IsUserInRole(string username, string roleName)
		{
			if (!UserRoles.ContainsKey(username)) AddUserWithDefaultRoles(username);
			return UserRoles[username].Contains(roleName);
		}

		public override void RemoveUsersFromRoles(string[] usernames, string[] roleNames)
		{
			throw new NotImplementedException();
		}

		public override bool RoleExists(string roleName)
		{
			return GalleryRoles.AllRoles.Contains(roleName);
		}

		private void AddUserWithDefaultRoles(string username)
		{
			UserRoles[username] = new SortedSet<string> {GalleryRoles.Upload, GalleryRoles.EditImage};
			Save();
		}
	}
}
